import Page from '@/components/Page';
import { Command } from '@tauri-apps/api/shell';
import { transformCallback } from '@tauri-apps/api/tauri';
import React, { useEffect, useRef } from 'react';
import { useLocation, useSearchParams } from 'react-router-dom';

function baseGet(object: any, path: string) {
  for (const item of path.split('.')) {
    object = object?.[item];
  }
  return object;
}
function get(object: any, path: string, defaultValue?: any) {
  var result = object == null ? undefined : baseGet(object, path);
  return result === undefined ? defaultValue : result;
}

function spawn({ program, args, options }: any, e: MessageEvent) {
  let child = null;
  const command = new Command(program, [...args], options);
  command.on('close', (data) => {
    e.ports[0].postMessage(
      JSON.stringify({
        close: data,
      }),
    ),
      (child = null);
  });
  command.on('error', (error) =>
    e.ports[0].postMessage(
      JSON.stringify({
        error,
      }),
    ),
  );
  command.stdout.on('data', (line) =>
    e.ports[0].postMessage(
      JSON.stringify({
        stdout: line,
      }),
    ),
  );
  command.stderr.on('data', (line) => {
    e.ports[0].postMessage(
      JSON.stringify({
        stderr: line,
      }),
    );
  });

  command
    .spawn()
    .then((c) => {
      child = c;
    })
    .catch((err) => {
      e.ports[0].postMessage(JSON.stringify(err));
    });
}

const Iframe = () => {
  const [params, _] = useSearchParams();
  const location: any = useLocation();
  const iframeRef = useRef<HTMLIFrameElement>(null);

  const handleMessage = async (e: MessageEvent) => {
    console.info(`send from iframe[${e.origin}]:`, e);
    const { __func__, args } = JSON.parse(e.data);
    if (!__func__) {
      e.ports[0].postMessage(
        JSON.stringify({ error: 'not found __func__' }),
      );
      return;
    }
    // @ts-ignore:next-line
    const func = get(window.__TAURI__, __func__);
    if (!func) {
      e.ports[0].postMessage(
        JSON.stringify({ error: 'not found func' }),
      );
      return;
    }

    const isShell = args[0] == 'tauri' &&
      args[1]?.__tauriModule == 'Shell' &&
      args[1]?.message?.cmd == 'execute'
    if (isShell) {
      args[1].message.onEventFn = transformCallback((event: any) => {
        console.log("iframe shell:", event)
        e.ports[0].postMessage(JSON.stringify(event));
      });
    }
    try {
      const res = await func(...args);
      e.ports[0].postMessage(JSON.stringify(res));
    } catch (error) {
      console.warn(error);
    }
  }
  useEffect(() => {
    window.addEventListener('message', handleMessage);
    return () => {
      console.log("Exit Iframe");
      window.removeEventListener("message", handleMessage)
    }
  }, [location?.state?.url]);
  return (
    <Page
      title={location?.state?.title as string}
      bodyStyle={{ margin: 0, padding: 0 }}
    >
      <iframe
        ref={iframeRef}
        src={location?.state?.url as string}
        style={{
          border: 'none',
          height: 'calc(100vh - 77px)',
          width: '100%',
        }}
      ></iframe>
    </Page>
  );
};

export default Iframe;
